{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Interactive Maps for Google Earth Engine Python API\n",
    "\n",
    "### This notebook is a showcase of a new feature of `geetools`, and it is still under active development on https://github.com/gee-community/gee_tools. There are 2 options:\n",
    "\n",
    "## 1. maptool\n",
    "### Based on https://github.com/mccarthyryanc/folium_gee but improved in order to 'emulate' the behavior of Map in the Code Editor. \n",
    "#### Pros:\n",
    "1. This module can be use to generate html for other purposes like webapps, etc\n",
    "2. Can change zoom with mouse scroll\n",
    "\n",
    "#### Cons:\n",
    "1. When using this module you have to complete the Map (addLayer, etc), and at the end use `Map.show()` to show the map. Can't add more layers afterwards.\n",
    "2. Takes a long time to show the map\n",
    "\n",
    "## 2. ipymap\n",
    "### Based on https://github.com/gee-community/ee-jupyter-contrib/blob/master/examples/getting-started/display-interactive-map.ipynb\n",
    "#### Pros and cons are the opposite to `maptool`\n",
    "\n",
    "#### *(I'll try to keep this notebook up to date)*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Make imports"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import ee\n",
    "ee.Initialize()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Get an image"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "col = ee.ImageCollection('COPERNICUS/S2')\n",
    "site = ee.Geometry.Point([-72, -42])\n",
    "col = col.filterBounds(site).filterMetadata('CLOUD_COVERAGE_ASSESSMENT', 'less_than', 40)\n",
    "i = ee.Image(col.first())\n",
    "igeom = i.geometry()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# define visualization parameters (dict)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "visParam = {'bands':['B8', 'B11', 'B4'], 'min':0, 'max':5000}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## define inspection\n",
    "### `addLayer` has a parameter called `inspect` that defines de content for a pop up, which is a dict with the following keys:\n",
    "1. data: eeObject from where to get the data\n",
    "2. reducer: can be 'first', 'mean', 'media' and 'sum'\n",
    "3. scale: scale to use in the reduction. If not provided, it uses the nominalScale for the image's first band"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "inspect = {'data':i, 'reducer':'mean'}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Plot the image into an interactive Map using `maptool` (Folium)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from geetools.ui import maptool\n",
    "Map = maptool.Map()\n",
    "\n",
    "Map.addLayer(i, visParam, 'Sentinel 2 Patagonia')\n",
    "Map.centerObject(i)\n",
    "\n",
    "Map.addLayer(igeom, name='Image boundries', inspect=inspect)\n",
    "\n",
    "Map.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Plot the image into an interactive Map using `ipymap` (ipyleaflet)\n",
    "## This Map has extra features:\n",
    "1. Inspector\n",
    "2. Tasks\n",
    "3. Assets\n",
    "\n",
    "### At the moment, the only one working is the inspector"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## First plot an empty Map (you can add stuff here too)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from geetools import ui\n",
    "Map2 = ui.Map()\n",
    "\n",
    "# you can do also:\n",
    "# from geetools.ui import ipymap\n",
    "# Map2 = ipymap.Map()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "Map2.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## addLayer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Map2.addLayer(i, visParam, 'Sentinel 2 Patagonia')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Map2.addLayer(i, {'bands':['B8'], 'min':0, 'max':5000}, 'just B8')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Center an Image"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Map2.centerObject(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## addLayer Geometry"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Map2.addLayer(igeom, name='Image boundries')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Center a Geometry"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Map2.centerObject(igeom)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get Map Center"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "center = Map2.getCenter()\n",
    "center.getInfo()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get Map Bounds"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "bounds = Map2.getBounds()\n",
    "bounds.getInfo()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Remove a layer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Map2.removeLayer('Sentinel 2 Patagonia')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# TABS\n",
    "## You can add a custom Tab with a custom handler. The handler is a function with 4 main parameters:\n",
    "- **type:** the interaction type. Can be 'click', 'mouseover', etc\n",
    "- **coordinates:** the coordinates where the interaction has taken place. If you have used ipyleaflet before, take in consideraton that coordinates are inverted (to match GEE format): [longitud, latitude]\n",
    "- **widget:** The widget inside the Tab. Defaults to an empty HTML widget\n",
    "- **map:** the Map instance. You can apply any of its methods, or get any of its properties"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(Map2.addTab.__doc__)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def test_handler(**change):    \n",
    "    # PARAMS\n",
    "    ty = change['type']\n",
    "    coords = change['coordinates']\n",
    "    wid = change['widget']\n",
    "    themap = change['map']\n",
    "        \n",
    "    if ty == 'click':  # If interaction was a click\n",
    "        # Loading message before sending a request to EE\n",
    "        wid.value = 'Loading...'\n",
    "        # Map's bounds\n",
    "        bounds = themap.getBounds().getInfo()['coordinates']\n",
    "        # Change Widget Value\n",
    "        wid.value = \"You have clicked on {} and map's bounds are {}\".format(coords, bounds)\n",
    "\n",
    "Map2.addTab('TestTAB', test_handler)\n",
    "print(\"Check out the Map!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
